package com.xzx.helloworld;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;

/**
 *  * @author xinzhixuan
 * @version 1.0
 * @date 2025/10/14 12:01
 */
public class DiscardServer {
    public static void main(String[] args) {
        /**
         * NioEventLoopGroup是一个处理IO操作的多线程事件循环。
         * Netty为不同类型的传输提供了各种EventLoopGroup实现。
         * 在本例中，我们将实现一个服务器端应用程序，因此将使用两个NioEventLoopGroup。
         * 第一个通常被称为“boss”，它接受连接。
         * 第二个通常称为“worker”，一旦boss接受连接并将接受的连接注册到worker，它将处理已接受连接的流量。
         * 使用多少线程以及如何将它们映射到创建的通道取决于EventLoopGroup实现，甚至可以通过构造函数进行配置。
         */
        NioEventLoopGroup bossGroup = new NioEventLoopGroup();
        NioEventLoopGroup workerGroup = new NioEventLoopGroup();

        try {
            /**
             * ServerBootstrap是一个设置服务器的助手类。
             * 您可以直接使用Channel设置服务器。但是，请注意，这是一个繁琐的过程，在大多数情况下您不需要这样做
             */
            ServerBootstrap serverBootstrap = new ServerBootstrap()
                    .group(bossGroup, workerGroup)
                    //在这里，我们指定使用NioServerSocketChannel类，该类用于实例化一个新Channel以接受传入的连接
                    .channel(NioServerSocketChannel.class)
                    // 你可以添加一些针对Channel的参数
                    // 我们正在编写一个TCPIP服务器，因此我们可以设置socket的一些参数，如tcpNoDelay和keepAlive。
                    // 请参考ChannelOption的apidocs和特定的ChannelConfig实现，以获得有关支持的ChannelOptions的概述
                    .option(ChannelOption.SO_BACKLOG, 128)
                    //你注意到option（）和childOption（）了吗？
                    // option（）用于NioServerSocketChannel，它接收客户端连接。
                    // childOption（）用于父ServerChannel接受的通道，在本例中为NioSocketChannel。
                    .childOption(ChannelOption.SO_KEEPALIVE, true)
                    // 当有新的channel被接受时，该handler将被调用
                    // ChannelInitializer是一个特殊的handler，用于帮助用户配置一个新的Channel。
                    // 很可能你想通过添加一些handler（如DiscardServerHandler）来配置一个新channel的ChannelPipeline，以实现网络应用程序。
                    // 随着应用程序变得复杂，可能会向管道中添加更多handler，并最终将这个匿名类提取到顶级类中。
                    .childHandler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        protected void initChannel(SocketChannel ch) throws Exception {
                            ch.pipeline().addLast(new DiscardServerHandler());
                        }
                    });
            // 绑定端口并启动服务, 这里我们绑定了 9999 端口
            ChannelFuture future = serverBootstrap.bind(9999).sync();
            System.out.println("Server started.");
            future.channel().closeFuture().sync();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            bossGroup.shutdownGracefully();
            workerGroup.shutdownGracefully();
        }

    }
}
